package com.sky.service.impl.admin;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.BaseException;
import com.sky.mapper.admin.SetmealDishMapper;
import com.sky.mapper.admin.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.admin.SetmealService;
import com.sky.vo.SetmealVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;


@Service
@Slf4j
public class SetmealServcicelmpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Result<PageResult> getSetmealByPage(SetmealPageQueryDTO dto) {
        PageHelper.startPage(dto.getPage(), dto.getPageSize());

        List<SetmealVO> setmealVOList = setmealMapper.getSetmealByPage(dto);

        PageInfo<SetmealVO> pageInfo = new PageInfo<>(setmealVOList);

        return Result.success(new PageResult(pageInfo.getTotal(), pageInfo.getList()));
    }

    @Override
    public Result<Object> addSetmeal(SetmealDTO dto) {

        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(dto, setmeal);

        // 插入套餐数据
        if (setmealMapper.addSetmeal(setmeal) == 0) throw new BaseException("套餐增加失败");

        // 插入套餐关联的菜品数据
        List<SetmealDish> setmealDishList = dto.getSetmealDishes();
        if (setmealDishList != null && !setmealDishList.isEmpty()) {
            // 回写关联外键
            setmealDishList.forEach(e -> e.setSetmealId(setmeal.getId()));
            setmealDishMapper.addsetmealDishByList(setmealDishList);
        }
        return Result.success();
    }

    @Override
    public Result<Object> getSetmealAllInfoById(Long id) {
        SetmealVO setmealVO = setmealMapper.getSetmealAllInfoById(id);
        if (setmealVO == null) throw new BaseException("套餐查询异常");


        List<SetmealDish> setmealDishList = setmealDishMapper.getSetmealDishInfoBysetmealId(id);

        setmealVO.setSetmealDishes(setmealDishList);

        return Result.success(setmealVO);
    }

    @Override
    @Transactional
    public Result<Object> setSetmealStatusById(Long status, Long id) {
        Setmeal setmeal = Setmeal.builder().status(status.intValue()).id(id).build();

        if (setmeal.getStatus().equals(StatusConstant.DISABLE)) {
            if (setmealDishMapper.getEnableSetmealDishCountBySetmealId(id) > 0)
                return Result.error(MessageConstant.SETMEAL_ENABLE_FAILED);
        }

        if (setmealMapper.updateSetmeal(setmeal) == 0) throw new BaseException("修改套餐状态失败");

        return Result.success();


    }

    @Override
    @Transactional
    public Result<Object> setSetmealById(SetmealDTO dto) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(dto, setmeal);


        // 修改套餐数据 不包括菜单关联菜品
        if (setmealMapper.updateSetmeal(setmeal) == 0) throw new BaseException("修改菜品信息失败");

        // 修改或增加套餐关联菜品数据
        // 修改套餐关联菜品规则
        // 1.如果修改的是菜品的份数 只需更改原有数据中的菜品份数
        // 2.添加菜品 则插入新数据
        // 3.如果将之前套餐关联的菜品进行删除，则对应的记录也要删除

        // TODO 不如这样做： 直接删掉当前套餐的关联的菜品数据，然后重新插入新的菜品数据

        // 获取到套餐修改后的关联菜品数据
        List<SetmealDish> setmealDishList = dto.getSetmealDishes();

        if (setmealDishList == null || setmealDishList.isEmpty()) return Result.error("关键参数菜品信息未传递");

        // 删除套餐之前关联的菜品数据
        if (setmealDishMapper.removeSetmealDishBySetmealId(setmeal.getId()) == 0)
            throw new BaseException("修改套餐关联菜品信息失败");

        // 插入修改过的套餐关联菜品数据
        // 回写关联外键
        setmealDishList.forEach(e -> e.setSetmealId(setmeal.getId()));
        setmealDishMapper.addsetmealDishByList(setmealDishList);

        return Result.success();
    }

    @Override
    public Result<Object> deleteSetmealById(String ids) {
        List<Long> idList = Arrays.stream(ids.split(",")).map(Long::valueOf).toList();

        // 判断要删除的套餐是否起售
        List<Setmeal> enableSetmealList = setmealMapper.getEnableSetmealCountByIds(idList);
        if (enableSetmealList != null && !enableSetmealList.isEmpty())
            return Result.error(MessageConstant.SETMEAL_ON_SALE);

        // 删除套餐
        if (setmealMapper.deleteSetmealByIds(idList) == 0) throw new BaseException("删除套餐失败");

        return Result.success();
    }

    @Override
    @Cacheable(cacheNames = "setmeal", key = "#categoryId")
    public Result<List<Setmeal>> getSetmealByCategoryId(Long categoryId) {
        List<Setmeal> list = setmealMapper.getSetmealByCategoryId(categoryId);

        return Result.success(list);
    }

    @Override
    @Cacheable(cacheNames = "setmealDish", key = "#id")
    public Result<List<SetmealDish>> getDishItemById(Long id) {

        List<SetmealDish> list = setmealDishMapper.getSetmealDishInfoBysetmealId(id);

        return Result.success(list);
    }


}
